package cn.flying.cloud.base.common.sensitive.serializer;

import java.io.IOException;
import java.util.Objects;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;

import cn.flying.cloud.base.common.sensitive.annotation.SensitiveInfo;
import cn.flying.cloud.base.common.sensitive.enums.SensitiveType;

/**
 * 脱敏序列化方式
 *
 * @author: admin
 * @date: 2025年09月24日 11:29
 * @version: 1.0
 */
public class SensitiveInfoSerializer extends JsonSerializer<String> implements ContextualSerializer {

    private SensitiveType sensitiveType;

    public SensitiveInfoSerializer(SensitiveType sensitiveType) {
        this.sensitiveType = sensitiveType;
    }

    public SensitiveInfoSerializer() {
    }

    @Override
    public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        if (value == null) {
            gen.writeNull();
            return;
        }

        switch (sensitiveType) {
            case NAME:
                gen.writeString(desensitizeName(value));
                break;
            case ID_CARD:
                gen.writeString(desensitizeIdCard(value));
                break;
            case PHONE:
                gen.writeString(desensitizePhone(value));
                break;
            case EMAIL:
                gen.writeString(desensitizeEmail(value));
                break;
            case ADDRESS:
                gen.writeString(desensitizeAddress(value));
                break;
            default:
                gen.writeString(value);
        }
    }

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {
        SensitiveInfo annotation = property.getAnnotation(SensitiveInfo.class);
        if (Objects.nonNull(annotation) && Objects.equals(String.class, property.getType().getRawClass())) {
            return new SensitiveInfoSerializer(annotation.value());
        }
        return prov.findValueSerializer(property.getType(), property);
    }

    // 姓名脱敏：保留姓氏
    private String desensitizeName(String name) {
        if (name == null || name.length() <= 1) {
            return name;
        }
        StringBuilder sb = new StringBuilder();
        sb.append(name.charAt(0));
        for (int i = 1; i < name.length(); i++) {
            sb.append("*");
        }
        return sb.toString();
    }

    // 身份证号脱敏：保留前6位和后4位
    private String desensitizeIdCard(String idCard) {
        if (idCard.length() <= 10) {
            return idCard;
        }
        return idCard.substring(0, 6) + "********" + idCard.substring(idCard.length() - 4);
    }

    // 手机号脱敏：保留前3位和后4位
    private String desensitizePhone(String phone) {
        if (phone.length() != 11) {
            return phone;
        }
        return phone.substring(0, 3) + "****" + phone.substring(7);
    }

    // 邮箱脱敏：保留@前的第一个字符和域名
    private String desensitizeEmail(String email) {
        int index = email.indexOf("@");
        if (index <= 1) {
            return email;
        }
        return email.charAt(0) + "*****" + email.substring(index);
    }

    // 地址脱敏：保留前6位，后面用***代替
    private String desensitizeAddress(String address) {
        if (address.length() <= 6) {
            return address;
        }
        return address.substring(0, 6) + "***";
    }
}